Skip to content

✨ Add MLIR pass for merging rotation gates #1019

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 45 commits into from
Jul 3, 2025
Merged

✨ Add MLIR pass for merging rotation gates #1019

merged 45 commits into from
Jul 3, 2025

Conversation

denialhaag
Copy link
Collaborator

@denialhaag denialhaag commented Jun 23, 2025

Description

This PR adds a pass for merging simple rotation gates.

Fixes #898

Checklist:

  • The pull request only contains commits that are focused and relevant to this change.
  • I have added appropriate tests that cover the new/changed functionality.
  • I have updated the documentation to reflect these changes.
  • I have added entries to the changelog for any noteworthy additions, changes, fixes or removals.
  • I have added migration instructions to the upgrade guide (if needed).
  • The changes follow the project's style guidelines and introduce no new warnings.
  • The changes are fully tested and pass the CI checks.
  • I have reviewed my own code changes.

@denialhaag denialhaag self-assigned this Jun 23, 2025
@denialhaag
Copy link
Collaborator Author

So far, this PR adds a pass that can merge the following gates:

  • gphase
  • rx, ry, rz
  • rxx, ryy, rzz, rzx

I'm not sure about how to merge the remaining gates mentioned in #898. I have the feeling that they are fundamentally different and cannot be merged as easily because the respective gates cannot be decomposed into something that commutes.

I also still have to figure out why the tests are failing on Windows.

I already texted you privately, but if you have any input, I would be very interested, @burgholzer, @DRovara, and @ystade. :)

@DRovara
Copy link
Collaborator

DRovara commented Jun 25, 2025

I'm not sure about how to merge the remaining gates mentioned in #898. I have the feeling that they are fundamentally different and cannot be merged as easily because the respective gates cannot be decomposed into something that commutes.

I did some more thinking on this topic and I might have an idea: Rotations by Euler Angles are known to be difficult to compose from multiple rotations. That's why quaternions (https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation) are often used by game engines to represent rotations.

I think we might be able to do the same thing here: first translate the three Euler angles to quaternions, then we combine the multiple rotations into one single rotation and then we translate back into Euler angles. If you want we can also chat about this in person tomorrow, @denialhaag.

@burgholzer
Copy link
Member

I'm not sure about how to merge the remaining gates mentioned in #898. I have the feeling that they are fundamentally different and cannot be merged as easily because the respective gates cannot be decomposed into something that commutes.

I did some more thinking on this topic and I might have an idea: Rotations by Euler Angles are known to be difficult to compose from multiple rotations. That's why quaternions (https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation) are often used by game engines to represent rotations.

I think we might be able to do the same thing here: first translate the three Euler angles to quaternions, then we combine the multiple rotations into one single rotation and then we translate back into Euler angles. If you want we can also chat about this in person tomorrow, @denialhaag.

Have a look at the current Qiskit code in that regard. I remember that they are doing something very similar in the code since recently. Might serve as some good inspiration.

The rules for u gates should be fairly straight forward, I believe. u2 is only a special case of u so that should work similarly.

The two qubit gates are a bit more special.
I think that two of these with the same beta value just add up the angles of the first parameter. I am not aware of any more general rules for that at the moment.

In general, merging might not be particularly easy here. But cancellation is fairly easy to decide as also indicated by the code linked in the issue description. Maybe those gates should be included as special rules there.

Just my two cents here though.

@denialhaag
Copy link
Collaborator Author

denialhaag commented Jun 26, 2025

I did some more thinking on this topic and I might have an idea: Rotations by Euler Angles are known to be difficult to compose from multiple rotations. That's why quaternions (https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation) are often used by game engines to represent rotations.

I think we might be able to do the same thing here: first translate the three Euler angles to quaternions, then we combine the multiple rotations into one single rotation and then we translate back into Euler angles. If you want we can also chat about this in person tomorrow, @denialhaag.

@DRovara, yes, an in-person chat would be nice! I'll be in the office in a bit! :)

@denialhaag
Copy link
Collaborator Author

denialhaag commented Jun 26, 2025

Have a look at the current Qiskit code in that regard. I remember that they are doing something very similar in the code since recently. Might serve as some good inspiration.

The rules for u gates should be fairly straight forward, I believe. u2 is only a special case of u so that should work similarly.

The two qubit gates are a bit more special. I think that two of these with the same beta value just add up the angles of the first parameter. I am not aware of any more general rules for that at the moment.

In general, merging might not be particularly easy here. But cancellation is fairly easy to decide as also indicated by the code linked in the issue description. Maybe those gates should be included as special rules there.

Just my two cents here though.

@burgholzer, thanks for the ideas! I'll have a look at the Qiskit implementation!

@denialhaag
Copy link
Collaborator Author

For reference, the Qiskit pass is implemented here.

Copy link
Collaborator

@DRovara DRovara left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot for the effort! I made some comments with suggestions, feel free to look into them.

One more thing though: As far as I see, this will only work if the parameters are passed as operands and won't work if the parameters are static attributes. This is okay for now, but we should probably keep this in mind and at the very least open a follow-up issue for that.

@denialhaag denialhaag added feature New feature or request c++ Anything related to C++ code MLIR Anything related to MLIR labels Jun 27, 2025
@denialhaag
Copy link
Collaborator Author

For reference, the Qiskit pass is implemented here.

I created #1029. 👍

@denialhaag
Copy link
Collaborator Author

After an offline discussion with @DRovara, I removed the feature of erasing gates whose parameters meet the necessary conditions. This should only be supported for gates with static parameters. To this end, I created #1030.

@DRovara
Copy link
Collaborator

DRovara commented Jun 30, 2025

After an offline discussion with @DRovara, I removed the feature of erasing gates whose parameters meet the necessary conditions. This should only be supported for gates with static parameters. To this end, I created #1030.

Just for context, the idea was

rx(a), rx(b) ==> rx(a + b), then if a + b === 0, the gate can be removed.

However, since this PR works with dynamic operands, we can't really know if a + b === 0.
The previous solution was to check if a and b were arith.constant expressions and getting their numeric values from there, but in my opinion, it makes sense to have this idea covered by a different constant folding path that converts the arguments from dynamic operands to static attributes.

Once we have that, a + b === 0 can be checked in the merge process for rotation gates that use static attributes (see #1030).

@denialhaag denialhaag changed the title ✨ MLIR - Add pass for merging rotation gates ✨ Add MLIR pass for merging rotation gates Jun 30, 2025
@denialhaag denialhaag marked this pull request as ready for review June 30, 2025 17:10
Copy link
Collaborator

@DRovara DRovara left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I gave the PR another look and I just have some small comments left. I hope they should be addressable without too much effort.

Especially regarding the test cases, I think it is good to set up a good standard early.

Thanks a lot!

Copy link
Collaborator

@DRovara DRovara left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, thanks for the effort! Once the CI is passing, I'm happy with merging this PR - unless @burgholzer wants to have another look, too.

Signed-off-by: Lukas Burgholzer <[email protected]>
Copy link
Member

@burgholzer burgholzer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Many thanks for all the work on this 🙏🏼 great to see more and more MLIR passes making it into the repository.

I have a couple of comments, which hopefully are fairly easy to address/comment on. One potential simplification, a missing gate, and two more general comments/questions on potential canonicalizations that we are missing.

Copy link
Member

@burgholzer burgholzer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome. Thanks for the changes. This is ready to go in 🚀

@burgholzer burgholzer merged commit ec778f4 into main Jul 3, 2025
22 checks passed
@burgholzer burgholzer deleted the merge-pass branch July 3, 2025 12:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c++ Anything related to C++ code feature New feature or request MLIR Anything related to MLIR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

✨ MLIR - Rotation Gate Merge Pass/Pattern
3 participants